package org.akomantoso.core.io.util;

import java.io.IOException;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

import org.akomantoso.core.data.ComponentRef;
import org.akomantoso.core.data.HierarchyElement;
import org.akomantoso.core.data.Wrap;
import org.akomantoso.core.io.Input;
import org.akomantoso.core.io.InputConstants;
import org.akomantoso.core.io.util.group.HierElementsGroup;
import org.akomantoso.core.util.MapUtil;

public class HierarchyElementUtil {

	private HierarchyElementUtil() {
	}

	static final Map<String, Instantiator<HierarchyElement>> MAP;

	private static HierarchyElement instantiate(String elementName) {

		final Instantiator<HierarchyElement> instatiator = MAP.get(elementName);
		if (instatiator == null) {
			throw new RuntimeException("Tag [" + elementName + "] not supported for HierarchyElement ?!?");
		}
		return instatiator.instantiate();
	}
	
	public static void read(Input in, List<HierarchyElement> elements, String localName) throws IOException {
		HierarchyElement element = null;
		int eventType = in.getEventType();
		while (true) {
			switch (eventType) {
			case InputConstants.START_ELEMENT:
				if (Wrap.ELEMENT == in.getLocalName()) {
					return;
				}
				elements.add(element = instantiate(in.getLocalName()));
				element.readExternal(in);
				break;
			case InputConstants.END_ELEMENT:
				if (localName == in.getLocalName()) {
					return;
				}
			}
			eventType = in.readNext();
		}
	}

	static {
		Map<String, Instantiator<HierarchyElement>> temp = new IdentityHashMap<String, Instantiator<HierarchyElement>>();
		
		MapUtil.copy(HierElementsGroup.MAP, temp);
		
		temp.put(ComponentRef.ELEMENT.intern(), new Instantiator<HierarchyElement>() {
			public ComponentRef instantiate() {
				return new ComponentRef();
			}
		});
		MAP = temp;
	}
	
}